﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;

namespace HangerSupport
{
	public class AddSeismicComponent
	{
		public AddSeismicComponent(Autodesk.Revit.DB.Document doc)
		{
			this.uiDoc = new UIDocument(doc);
		}

		public AddSeismicComponent(Autodesk.Revit.DB.Document doc, DlgAddSeismicComponent dlg)
		{
			this.dlg = dlg;
			this.doc = doc;
			this.uiDoc = new UIDocument(doc);
		}

		public AddSeismicComponent(Autodesk.Revit.DB.Document doc, SeismicComponentModel scm, FamilySymbol fs)
		{
			this.doc = doc;
			this.scm = scm;
			this.fs = fs;
		}

		public void Execute()
		{
			this.tran = new Transaction(this.doc, "抗震组件添加");
			this.LoadFamilySymbol();
			for (;;)
			{
				Autodesk.Revit.DB.View activeView = this.doc.ActiveView;
				try
				{
					bool flag = this.fs == null;
					if (flag)
					{
						YJKMessageBox.Information("未加载到抗震组件族！");
						break;
					}
					this.hsType = this.dlg.HsType;
					List<Element> hanger = this.GetHanger();
					this.dlg.CmdEsc = true;
					bool flag2 = hanger == null || hanger.Count < 1;
					if (!flag2)
					{
						this.scm = this.dlg.Scm;
						bool flag3 = !this.Validating(this.scm, ref this.exMessage);
						if (flag3)
						{
							YJKMessageBox.Information(this.exMessage);
						}
						else
						{
							this.tran.Start();
							int num = this.addSeismicComponents(hanger);
							bool flag4 = num > 0;
							if (flag4)
							{
								YJKMessageBox.Information(string.Format("由于布置高度过小，造成 {0} 个组件无法正常布置！", num));
							}
							this.tran.Commit();
						}
					}
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
				{
					Autodesk.Revit.DB.View activeView2 = this.doc.ActiveView;
					this.exMessage = ex.ToString();
					bool flag5 = RevitVersionFuncs.GetViewName(activeView) == RevitVersionFuncs.GetViewName(activeView2);
					if (flag5)
					{
						break;
					}
				}
				catch (Exception ex2)
				{
					this.exMessage = ex2.ToString();
					bool cmdEsc = this.dlg.CmdEsc;
					if (cmdEsc)
					{
						break;
					}
				}
				finally
				{
					bool flag6 = this.tran != null && (int)this.tran.GetStatus() != 3 && (int)this.tran.GetStatus() != 2;
					if (flag6)
					{
						this.tran.RollBack();
					}
				}
			}
		}

		private bool Validating(SeismicComponentModel scm, ref string message)
		{
			bool flag = this.dlg.hyTxtAngleA.Enabled && (scm.location_A_Angle.Value < 22.5 || scm.location_A_Angle.Value > 67.5);
			bool result;
			if (flag)
			{
				message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
				result = false;
			}
			else
			{
				bool flag2 = this.dlg.hyTxtAngleB.Enabled && (scm.location_B_Angle.Value < 22.5 || scm.location_B_Angle.Value > 67.5);
				if (flag2)
				{
					message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
					result = false;
				}
				else
				{
					bool flag3 = this.dlg.hyTxtAngleC.Enabled && (scm.location_C_Angle.Value < 22.5 || scm.location_C_Angle.Value > 67.5);
					if (flag3)
					{
						message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
						result = false;
					}
					else
					{
						bool flag4 = this.dlg.hyTxtAngleD.Enabled && (scm.location_D_Angle.Value < 22.5 || scm.location_D_Angle.Value > 67.5);
						if (flag4)
						{
							message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
							result = false;
						}
						else
						{
							bool flag5 = scm.hsType != HSType.kDJ_DG;
							if (flag5)
							{
								bool flag6 = this.dlg.hyTxtAngleE.Enabled && (scm.location_E_Angle.Value < 22.5 || scm.location_E_Angle.Value > 67.5);
								if (flag6)
								{
									message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
									return false;
								}
								bool flag7 = this.dlg.hyTxtAngleF.Enabled && (scm.location_F_Angle.Value < 22.5 || scm.location_F_Angle.Value > 67.5);
								if (flag7)
								{
									message = "“抗震组件角度”需是在22.5°～67.5°范围内的有效数字!";
									return false;
								}
							}
							bool flag8 = this.dlg.hyTxtWidthB.Enabled && !this.ValidatingSize(scm.widthB, scm.hightH, scm.thickT);
							if (flag8)
							{
								message = "您输入的“抗震组件尺寸”不满足创建要求，无法生成抗震组件!";
								result = false;
							}
							else
							{
								result = true;
							}
						}
					}
				}
			}
			return result;
		}

		private bool ValidatingSize(double widthB, double hightH, double thickT)
		{
			return widthB > 0.0 && hightH > 0.0 && thickT > 0.0 && widthB > 3.0 * thickT + 4.0 && hightH > 4.0 * thickT + 8.0;
		}

		private void LoadFamilySymbol()
		{
			try
			{
				this.tran.Start();
				string text = "";
				this.fs = YJKRevitTools.GetFamilySymbolByName("HangerArm", "侧向支撑", this.doc, ref text);
				this.tran.Commit();
			}
			catch (Exception ex)
			{
				ex.ToString();
				this.fs = null;
			}
		}

		private List<Element> GetHanger()
		{
			List<string> lisFilterFamilyName = this.GetLisFilterFamilyName();
			List<Element> result;
			try
			{
				string text = string.Format("请选择需要添加抗震组件的支吊架({0})...", this.GetLayHangerTypeName());
				FilterElemsByFamilySymbolName filterElemsByFamilySymbolName = new FilterElemsByFamilySymbolName(lisFilterFamilyName);
				result = this.uiDoc.Selection.PickElementsByRectangle(filterElemsByFamilySymbolName, text).ToList<Element>();
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
			{
				bool flag = !this.dlg.CmdEsc;
				if (!flag)
				{
					throw ex;
				}
				result = null;
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		private string GetLayHangerTypeName()
		{
			string result = "";
			switch (this.dlg.HsType)
			{
			case HSType.kDJ_DC:
				result = "多层吊架";
				break;
			case HSType.kDJ_GJ:
				result = "钢筋吊架";
				break;
			case HSType.kDJ_DG:
				result = "单管吊架";
				break;
			}
			return result;
		}

		private List<string> GetLisFilterFamilyName()
		{
			List<string> list = new List<string>();
			switch (this.hsType)
			{
			case HSType.kDJ_DC:
				for (int i = 1; i < 16; i++)
				{
					list.Add(i + "层吊架");
				}
				break;
			case HSType.kDJ_GJ:
				list.Add("钢筋吊架");
				break;
			case HSType.kDJ_DG:
				list.Add("单管吊架");
				break;
			}
			return list;
		}

		public int addSeismicComponents(List<Element> elems)
		{
			XYZ activeRight = new XYZ(this.doc.ActiveView.RightDirection.Normalize().X, this.doc.ActiveView.RightDirection.Normalize().Y, 0.0).Normalize();
			XYZ activeUpDirection = new XYZ(this.doc.ActiveView.UpDirection.X, this.doc.ActiveView.UpDirection.Y, 0.0).Normalize();
			this.GetDatumDirection(ref activeRight, ref activeUpDirection);
			int num = 0;
			foreach (Element element in elems)
			{
				XYZ point = (element.Location as LocationPoint).Point;
				this.BingSeiComLocPoint(element as FamilyInstance, point);
				FamilyInstance familyInstance = element as FamilyInstance;
				bool flag = familyInstance != null;
				if (flag)
				{
					this.DeleteLastTimeAddSeiComs(familyInstance);
					XYZ xyz = (familyInstance.Location as LocationPoint).Point;
					this.fixedThickness = this.GetFixedThickness(familyInstance);
					Parameter selectedHangerHight = this.GetSelectedHangerHight(familyInstance);
					bool flag2 = this.GetCompentHeight(selectedHangerHight) * 304.8 < 420.0;
					if (flag2)
					{
						num++;
					}
					else
					{
						xyz = new XYZ(xyz.X, xyz.Y, xyz.Z + this.fixedThickness);
						XYZ fiFacingOrientation = familyInstance.FacingOrientation.Normalize();
						XYZ fiHandOrientation = familyInstance.HandOrientation.Normalize();
						double angleA = 0.0;
						double angleB = 0.0;
						double angleCD = 0.0;
						double angleEF = 0.0;
						this.GetRotateAngle(activeRight, activeUpDirection, fiFacingOrientation, fiHandOrientation, ref angleA, ref angleB, ref angleCD, ref angleEF);
						List<FamilyInstance> list = new List<FamilyInstance>();
						this.crossBeamNotLayNum = 0;
						bool flag3 = this.scm.hsType == HSType.kDJ_DG;
						if (flag3)
						{
							this.AddKDJ_DG(xyz, angleA, angleB, angleCD, angleEF, selectedHangerHight, ref list);
						}
						else
						{
							this.AddKDJ_DC_And_GJ(familyInstance, activeRight, activeUpDirection, xyz, fiFacingOrientation, fiHandOrientation, angleA, angleB, angleCD, angleEF, selectedHangerHight, ref list);
						}
						num += this.crossBeamNotLayNum;
						this.SetSeismicComponentParamValue(list);
						this.BingSeiComsToHanger(familyInstance, list);
					}
				}
			}
			return num;
		}

		private double GetFixedThickness(FamilyInstance fi)
		{
			double result = 0.0;
			Parameter parameter = fi.GetParameter("固件厚t");
			bool flag = parameter != null && parameter.HasValue;
			if (flag)
			{
				result = parameter.AsDouble();
			}
			return result;
		}

		private double GetCompentHeight(Parameter paramHight)
		{
			return paramHight.AsDouble() + this.fixedThickness;
		}

		private void AddKDJ_DC_And_GJ(FamilyInstance fi, XYZ activeRight, XYZ activeUpDirection, XYZ basePoint, XYZ fiFacingOrientation, XYZ fiHandOrientation, double angleA, double angleB, double angleCD, double angleEF, Parameter paramHight, ref List<FamilyInstance> addSeiComs)
		{
			XYZ location = basePoint;
			XYZ location2 = basePoint;
			Parameter selectedHangerWidth = this.GetSelectedHangerWidth(fi);
			bool flag = selectedHangerWidth != null && selectedHangerWidth.HasValue;
			if (flag)
			{
				this.GetLayLocation(activeRight, activeUpDirection, basePoint, fiFacingOrientation, fiHandOrientation, selectedHangerWidth, out location, out location2);
			}
			bool flag2 = this.scm.location_A_Angle.Value != 0.0;
			if (flag2)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location, angleA, this.scm.location_A_Angle.Value, "A", paramHight));
			}
			bool flag3 = this.scm.location_B_Angle.Value != 0.0;
			if (flag3)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location2, angleB, this.scm.location_B_Angle.Value, "B", paramHight));
			}
			bool flag4 = this.scm.location_C_Angle.Value != 0.0;
			if (flag4)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location, angleCD, this.scm.location_C_Angle.Value, "C", paramHight));
			}
			bool flag5 = this.scm.location_E_Angle.Value != 0.0;
			if (flag5)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location, angleEF, this.scm.location_E_Angle.Value, "E", paramHight));
			}
			bool flag6 = this.scm.location_D_Angle.Value != 0.0;
			if (flag6)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location2, angleCD, this.scm.location_D_Angle.Value, "D", paramHight));
			}
			bool flag7 = this.scm.location_F_Angle.Value != 0.0;
			if (flag7)
			{
				addSeiComs.Add(this.CreateSeismicComponent(location2, angleEF, this.scm.location_F_Angle.Value, "F", paramHight));
			}
		}

		private void AddKDJ_DG(XYZ basePoint, double angleA, double angleB, double angleCD, double angleEF, Parameter paramHight, ref List<FamilyInstance> addSeiComs)
		{
			bool flag = this.scm.location_A_Angle.Value != 0.0;
			if (flag)
			{
				addSeiComs.Add(this.CreateSeismicComponent(basePoint, angleA, this.scm.location_A_Angle.Value, "A", paramHight));
			}
			bool flag2 = this.scm.location_B_Angle.Value != 0.0;
			if (flag2)
			{
				addSeiComs.Add(this.CreateSeismicComponent(basePoint, angleB, this.scm.location_B_Angle.Value, "B", paramHight));
			}
			bool flag3 = this.scm.location_C_Angle.Value != 0.0;
			if (flag3)
			{
				addSeiComs.Add(this.CreateSeismicComponent(basePoint, angleCD, this.scm.location_C_Angle.Value, "C", paramHight));
			}
			bool flag4 = this.scm.location_D_Angle.Value != 0.0;
			if (flag4)
			{
				addSeiComs.Add(this.CreateSeismicComponent(basePoint, angleEF, this.scm.location_D_Angle.Value, "D", paramHight));
			}
		}

		private void TranslateAngle(XYZ activeRight, XYZ activeUpDirection, ref double angleA, ref double angleB, ref double angleCD, ref double angleEF)
		{
			XYZ xyz = new XYZ(this.doc.ActiveView.RightDirection.X, this.doc.ActiveView.RightDirection.Y, 0.0);
			bool flag = xyz.AngleTo(activeRight) > 1.5807963267948966 || xyz.IsAlmostEqualTo(-activeUpDirection);
			if (flag)
			{
				double num = angleA;
				angleA = angleB;
				angleB = num;
				double num2 = angleCD;
				angleCD = angleEF;
				angleEF = num2;
			}
		}

		private void TranslateLocation(XYZ activeRight, XYZ activeUpDirection, ref XYZ ace, ref XYZ bdf)
		{
			XYZ xyz = new XYZ(this.doc.ActiveView.RightDirection.X, this.doc.ActiveView.RightDirection.Y, 0.0);
			bool flag = xyz.AngleTo(activeRight) > 1.5807963267948966 || xyz.IsAlmostEqualTo(-activeUpDirection);
			if (flag)
			{
				XYZ xyz2 = new XYZ(ace.X, ace.Y, ace.Z);
				ace = bdf;
				bdf = xyz2;
			}
		}

		private void GetLayLocation(XYZ activeRight, XYZ activeUpDirection, XYZ basePoint, XYZ fiFacingOrientation, XYZ fiHandOrientation, Parameter paramWidth, out XYZ ace, out XYZ bdf)
		{
			bool flag = paramWidth == null || !paramWidth.HasValue;
			if (flag)
			{
				ace = basePoint;
				bdf = basePoint;
			}
			else
			{
				bool flag2 = activeRight.AngleTo(fiHandOrientation) > 1.5807963267948966 && activeRight.AngleTo(fiHandOrientation) < 3.1315926535897933;
				if (flag2)
				{
					bool flag3 = fiHandOrientation.AngleTo(activeUpDirection) < 1.5607963267948965;
					if (flag3)
					{
						ace = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
						bdf = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
					}
					else
					{
						ace = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
						bdf = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
					}
				}
				else
				{
					bool flag4 = activeRight.AngleTo(fiHandOrientation) < 1.5607963267948965 && activeRight.AngleTo(fiHandOrientation) > 0.01;
					if (flag4)
					{
						bool flag5 = activeUpDirection.AngleTo(fiHandOrientation) > 1.5807963267948966;
						if (flag5)
						{
							ace = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
							bdf = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
						}
						else
						{
							ace = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
							bdf = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
						}
					}
					else
					{
						bool flag6 = fiHandOrientation.IsAlmostEqualTo(activeRight, 0.01) && fiFacingOrientation.IsAlmostEqualTo(activeUpDirection, 0.01);
						if (flag6)
						{
							ace = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
							bdf = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
						}
						else
						{
							bool flag7 = fiHandOrientation.IsAlmostEqualTo(activeUpDirection, 0.01) && fiFacingOrientation.IsAlmostEqualTo(-activeRight, 0.01);
							if (flag7)
							{
								ace = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
								bdf = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
							}
							else
							{
								bool flag8 = fiHandOrientation.IsAlmostEqualTo(-activeRight, 0.01) && fiFacingOrientation.IsAlmostEqualTo(-activeUpDirection, 0.01);
								if (flag8)
								{
									ace = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
									bdf = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
								}
								else
								{
									bool flag9 = fiHandOrientation.IsAlmostEqualTo(-activeUpDirection, 0.01) && fiFacingOrientation.IsAlmostEqualTo(activeRight, 0.01);
									if (flag9)
									{
										ace = basePoint - fiHandOrientation * paramWidth.AsDouble() / 2.0;
										bdf = basePoint + fiHandOrientation * paramWidth.AsDouble() / 2.0;
									}
									else
									{
										ace = basePoint;
										bdf = basePoint;
									}
								}
							}
						}
					}
				}
			}
		}

		private void GetRotateAngle(XYZ activeRight, XYZ activeUpDirection, XYZ fiFacingOrientation, XYZ fiHandOrientation, ref double angleA, ref double angleB, ref double angleCD, ref double angleEF)
		{
			bool flag = activeRight.IsAlmostEqualTo(fiHandOrientation, 0.01) && activeUpDirection.IsAlmostEqualTo(fiFacingOrientation, 0.01);
			if (flag)
			{
				angleA = fiHandOrientation.AngleTo(activeRight) - Math.PI;
				angleB = fiHandOrientation.AngleTo(activeRight);
				angleCD = fiFacingOrientation.AngleTo(activeRight);
				angleEF = fiFacingOrientation.AngleTo(activeRight) - Math.PI;
			}
			else
			{
				bool flag2 = activeRight.AngleTo(fiHandOrientation) > 0.01 && activeRight.AngleTo(fiHandOrientation) < 1.5607963267948965 && activeRight.AngleTo(fiFacingOrientation) > 1.5807963267948966 && activeRight.AngleTo(fiFacingOrientation) < 3.1315926535897933;
				if (flag2)
				{
					angleA = fiHandOrientation.AngleTo(activeRight);
					angleB = fiHandOrientation.AngleTo(activeRight) - Math.PI;
					angleCD = fiFacingOrientation.AngleTo(activeRight) - Math.PI;
					angleEF = fiFacingOrientation.AngleTo(activeRight);
				}
				else
				{
					bool flag3 = activeUpDirection.IsAlmostEqualTo(fiHandOrientation, 0.01) && activeRight.IsAlmostEqualTo(-fiFacingOrientation, 0.01);
					if (flag3)
					{
						angleA = fiHandOrientation.AngleTo(activeRight);
						angleB = fiHandOrientation.AngleTo(activeRight) - Math.PI;
						angleCD = fiFacingOrientation.AngleTo(activeRight) - Math.PI;
						angleEF = fiFacingOrientation.AngleTo(activeRight);
					}
					else
					{
						bool flag4 = activeRight.AngleTo(fiHandOrientation) > 1.5807963267948966 && activeRight.AngleTo(fiHandOrientation) < 3.1315926535897933 && activeRight.AngleTo(fiFacingOrientation) > 1.5807963267948966 && activeRight.AngleTo(fiFacingOrientation) < 3.1315926535897933;
						if (flag4)
						{
							angleA = fiHandOrientation.AngleTo(activeRight);
							angleB = fiHandOrientation.AngleTo(activeRight) - Math.PI;
							angleCD = Math.PI - fiFacingOrientation.AngleTo(activeRight);
							angleEF = -fiFacingOrientation.AngleTo(activeRight);
						}
						else
						{
							bool flag5 = activeUpDirection.IsAlmostEqualTo(-fiFacingOrientation, 0.01) && activeRight.IsAlmostEqualTo(-fiHandOrientation, 0.01);
							if (flag5)
							{
								angleA = fiHandOrientation.AngleTo(activeRight);
								angleB = fiHandOrientation.AngleTo(activeRight) - Math.PI;
								angleCD = fiFacingOrientation.AngleTo(activeRight);
								angleEF = fiFacingOrientation.AngleTo(activeRight) - Math.PI;
							}
							else
							{
								bool flag6 = activeRight.AngleTo(fiHandOrientation) > 1.5807963267948966 && activeRight.AngleTo(fiHandOrientation) < 3.1315926535897933 && activeRight.AngleTo(fiFacingOrientation) < 1.5607963267948965 && activeRight.AngleTo(fiFacingOrientation) > 0.01;
								if (flag6)
								{
									angleA = -fiHandOrientation.AngleTo(activeRight) + Math.PI;
									angleB = -fiHandOrientation.AngleTo(activeRight);
									angleCD = -fiFacingOrientation.AngleTo(activeRight);
									angleEF = Math.PI - fiFacingOrientation.AngleTo(activeRight);
								}
								else
								{
									bool flag7 = activeUpDirection.IsAlmostEqualTo(-fiHandOrientation, 0.01) && activeRight.IsAlmostEqualTo(fiFacingOrientation, 0.01);
									if (flag7)
									{
										angleA = fiHandOrientation.AngleTo(activeRight);
										angleB = fiHandOrientation.AngleTo(activeRight) - Math.PI;
										angleCD = fiFacingOrientation.AngleTo(activeRight);
										angleEF = -fiFacingOrientation.AngleTo(activeRight) + Math.PI;
									}
									else
									{
										bool flag8 = activeRight.AngleTo(fiHandOrientation) > 0.01 && activeRight.AngleTo(fiHandOrientation) < 1.5607963267948965 && activeRight.AngleTo(fiFacingOrientation) < 1.5607963267948965 && activeRight.AngleTo(fiFacingOrientation) > 0.01;
										if (flag8)
										{
											angleA = Math.PI - fiHandOrientation.AngleTo(activeRight);
											angleB = -fiHandOrientation.AngleTo(activeRight);
											angleCD = fiFacingOrientation.AngleTo(activeRight);
											angleEF = fiFacingOrientation.AngleTo(activeRight) - Math.PI;
										}
									}
								}
							}
						}
					}
				}
			}
		}

		private FamilyInstance CreateSeismicComponent(XYZ location, double rotate, double angle, string locat, Parameter paramHight)
		{
			rotate = rotate * 180.0 / Math.PI;
			FamilyInstance familyInstance = YJKRevitTools.LayFamilySymbol(this.doc, location, this.fs, rotate);
			this.doc.Regenerate();
			bool flag = familyInstance == null;
			FamilyInstance result;
			if (flag)
			{
				result = familyInstance;
			}
			else
			{
				Parameter parameter = familyInstance.GetParameters("侧向支撑角度").FirstOrDefault<Parameter>();
				bool flag2 = parameter != null && !parameter.IsReadOnly;
				if (flag2)
				{
					parameter.Set(UnitConvert.CovertToAPI(angle, (Autodesk.Revit.DB.DisplayUnitType)15));
				}
				bool flag3 = paramHight != null && paramHight.HasValue;
				if (flag3)
				{
					Parameter parameter2 = familyInstance.GetParameters("侧向支撑总高度").FirstOrDefault<Parameter>();
					bool flag4 = parameter2 != null && !parameter2.IsReadOnly;
					if (flag4)
					{
						parameter2.Set(this.GetCompentHeight(paramHight));
					}
				}
				Parameter parameter3 = familyInstance.GetParameters("位置标识").FirstOrDefault<Parameter>();
				bool flag5 = parameter3 != null && !parameter3.IsReadOnly;
				if (flag5)
				{
					parameter3.Set(locat);
				}
				this.doc.Regenerate();
				this.AdjustAngle(this.doc, familyInstance, location);
				result = familyInstance;
			}
			return result;
		}

		private void SetSeismicComponentParamValue(List<FamilyInstance> addSeiComs)
		{
			foreach (FamilyInstance familyInstance in addSeiComs)
			{
				Parameter parameter = familyInstance.GetParameters("斜撑b").FirstOrDefault<Parameter>();
				bool flag = parameter != null && !parameter.IsReadOnly;
				if (flag)
				{
					parameter.Set(this.scm.widthB / 304.8);
				}
				Parameter parameter2 = familyInstance.GetParameters("斜撑h").FirstOrDefault<Parameter>();
				bool flag2 = parameter2 != null && !parameter2.IsReadOnly;
				if (flag2)
				{
					parameter2.Set(this.scm.hightH / 304.8);
				}
				Parameter parameter3 = familyInstance.GetParameters("斜撑t").FirstOrDefault<Parameter>();
				bool flag3 = parameter3 != null && !parameter3.IsReadOnly;
				if (flag3)
				{
					parameter3.Set(this.scm.thickT / 304.8);
				}
			}
		}

		public void BingSeiComsToHanger(Element hanger, List<FamilyInstance> seismicComponents)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (Element element in seismicComponents)
			{
				stringBuilder.Append("@" + element.Id.IntegerValue.ToString());
			}
			Guid guid = new Guid("BBEC5246-99AA-45B9-A1B1-819109282C3B");
			bool flag = Schema.Lookup(guid) == null;
			Schema schema;
			if (flag)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
				schemaBuilder.SetReadAccessLevel((AccessLevel)1);
				schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetSchemaName("SeismicComponents");
				schemaBuilder.SetDocumentation("Bing add SeismicComponents");
				schemaBuilder.AddSimpleField("AddSeismicComponents", typeof(string));
				schemaBuilder.AddSimpleField("HangerSupportId", typeof(string));
				schema = schemaBuilder.Finish();
			}
			else
			{
				schema = Schema.Lookup(guid);
			}
			Entity entity = new Entity(schema);
			entity.Set<string>("AddSeismicComponents", stringBuilder.ToString());
			entity.Set<string>("HangerSupportId", hanger.Id.IntegerValue.ToString());
			hanger.SetEntity(entity);
		}

		public void DeleteLastTimeAddSeiComs(Element hanger)
		{
			Guid guid = new Guid("BBEC5246-99AA-45B9-A1B1-819109282C3B");
			bool flag = Schema.Lookup(guid) == null;
			if (!flag)
			{
				Entity entity = hanger.GetEntity(Schema.Lookup(guid));
				bool flag2 = entity.Schema == null;
				if (!flag2)
				{
					string tagIds = entity.Get<string>(Schema.Lookup(guid).GetField("AddSeismicComponents"));
					string text = entity.Get<string>(Schema.Lookup(guid).GetField("HangerSupportId"));
					bool flag3 = text.Equals(hanger.Id.IntegerValue.ToString());
					if (flag3)
					{
						this.Deletes(tagIds);
					}
				}
			}
		}

		private void Deletes(string tagIds)
		{
			char[] separator = new char[]
			{
				'@'
			};
			string[] array = tagIds.ToString().Split(separator, StringSplitOptions.RemoveEmptyEntries);
			string[] array2 = array;
			int i = 0;
			while (i < array2.Length)
			{
				string s = array2[i];
				int num;
				bool flag = int.TryParse(s, out num);
				if (flag)
				{
					ElementId elementId = new ElementId(num);
					Element element = this.doc.GetElement(elementId);
					try
					{
						bool flag2 = element != null;
						if (flag2)
						{
							this.doc.DeleteElement(element);
						}
					}
					catch (Exception)
					{
					}
				}
				IL_75:
				i++;
				continue;
				goto IL_75;
			}
		}

		public void BingSeiComLocPoint(FamilyInstance fi, XYZ locationPoint)
		{
			Guid guid = new Guid("A705CD05-18AE-4F55-8CE9-0C5C4AC8DC2F");
			bool flag = Schema.Lookup(guid) == null;
			Schema schema;
			if (flag)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
				schemaBuilder.SetReadAccessLevel((AccessLevel)1);
				schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetSchemaName("SeismicComponentLocationPoint");
				schemaBuilder.SetDocumentation("Record SeismicComponent locationPoint");
				schemaBuilder.AddSimpleField("locationX", typeof(string));
				schemaBuilder.AddSimpleField("locationY", typeof(string));
				schemaBuilder.AddSimpleField("locationZ", typeof(string));
				schema = schemaBuilder.Finish();
			}
			else
			{
				schema = Schema.Lookup(guid);
			}
			Entity entity = new Entity(schema);
			entity.Set<string>("locationX", locationPoint.X.ToString());
			entity.Set<string>("locationY", locationPoint.Y.ToString());
			entity.Set<string>("locationZ", locationPoint.Z.ToString());
			fi.SetEntity(entity);
		}

		private XYZ GetCreateSeiComLocPoint(FamilyInstance fi)
		{
			Guid guid = new Guid("A705CD05-18AE-4F55-8CE9-0C5C4AC8DC2F");
			bool flag = Schema.Lookup(guid) == null;
			XYZ result;
			if (flag)
			{
				result = null;
			}
			else
			{
				Entity entity = fi.GetEntity(Schema.Lookup(guid));
				bool flag2 = entity.Schema == null;
				if (flag2)
				{
					result = null;
				}
				else
				{
					double num = Convert.ToDouble(entity.Get<string>(Schema.Lookup(guid).GetField("locationX")));
					double num2 = Convert.ToDouble(entity.Get<string>(Schema.Lookup(guid).GetField("locationY")));
					double num3 = Convert.ToDouble(entity.Get<string>(Schema.Lookup(guid).GetField("locationZ")));
					result = new XYZ(num, num2, num3);
				}
			}
			return result;
		}

		private void GetDatumDirection(ref XYZ rightDir, ref XYZ upDir)
		{
			FamilyInstance familyInstance = YJKRevitTools.LayFamilySymbol(this.doc, new XYZ(), this.fs, 0.0);
			this.doc.Regenerate();
			bool flag = familyInstance != null;
			if (flag)
			{
				rightDir = familyInstance.HandOrientation.Normalize();
				upDir = familyInstance.FacingOrientation.Normalize();
			}
			this.doc.DeleteElement(familyInstance);
		}

		private Parameter GetSelectedHangerHight(FamilyInstance fi)
		{
			Parameter result = null;
			switch (this.scm.hsType)
			{
			case HSType.kDJ_DC:
				result = fi.GetParameters("根部高度").FirstOrDefault<Parameter>();
				break;
			case HSType.kDJ_GJ:
				result = fi.GetParameters("高").FirstOrDefault<Parameter>();
				break;
			case HSType.kDJ_DG:
				result = fi.GetParameters("高").FirstOrDefault<Parameter>();
				break;
			}
			return result;
		}

		private Parameter GetSelectedHangerWidth(FamilyInstance fi)
		{
			Parameter result = null;
			HSType hstype = this.scm.hsType;
			if (hstype != HSType.kDJ_DC)
			{
				if (hstype == HSType.kDJ_GJ)
				{
					result = fi.GetParameters("宽").FirstOrDefault<Parameter>();
				}
			}
			else
			{
				result = fi.GetParameters("净宽").FirstOrDefault<Parameter>();
			}
			return result;
		}

		private void AdjustAngle(Autodesk.Revit.DB.Document doc, Element elem, XYZ location)
		{
			double num = 0.0;
			XYZ xyz = (elem as FamilyInstance).HandOrientation.Normalize();
			Line beamLine = null;
			Element intersectBeam = this.GetIntersectBeam(doc, elem as FamilyInstance, ref beamLine);
			bool flag = intersectBeam != null;
			if (flag)
			{
				this.SetAngle(doc, elem, intersectBeam, beamLine, ref num);
			}
			else
			{
				Parameter parameter = elem.GetParameters("横向装置可见性").FirstOrDefault<Parameter>();
				bool flag2 = parameter != null && parameter.HasValue;
				if (flag2)
				{
					parameter.Set(1);
				}
			}
			XYZ locationPoint = location + XYZ.BasisZ * num;
			this.BingSeiComLocPoint(elem as FamilyInstance, locationPoint);
		}

		private Element GetIntersectingBeam(Autodesk.Revit.DB.Document doc, Element elem, XYZ elemHandOri, ref Line beamLine)
		{
			Element result = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			BoundingBoxXYZ boundingBoxXYZ = elem.get_BoundingBox(doc.ActiveView);
			XYZ min = boundingBoxXYZ.Min;
			XYZ max = boundingBoxXYZ.Max;
			Outline outline = new Outline(min, max);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline);
			List<Element> list = filteredElementCollector.OfCategory(BuiltInCategory.OST_StructuralFraming).WherePasses(boundingBoxIntersectsFilter).WhereElementIsNotElementType().ToElements().ToList<Element>();
			foreach (Element element in list)
			{
				beamLine = ((element.Location as LocationCurve).Curve as Line);
				bool flag = beamLine.Direction.AngleTo(elemHandOri) > 1.5607963267948965 && beamLine.Direction.AngleTo(elemHandOri) < 1.5807963267948966;
				if (flag)
				{
					result = element;
					break;
				}
			}
			return result;
		}

		private Element GetIntersectBeam(Autodesk.Revit.DB.Document doc, FamilyInstance fi, ref Line lineOnBeamFace)
		{
			Element element = null;
			lineOnBeamFace = null;
			List<Element> intersectElementSet = HYSystemElementFilter.GetIntersectElementSet(doc, fi, (Autodesk.Revit.DB.BuiltInCategory)(-2001320));
			bool flag = intersectElementSet == null || intersectElementSet.Count < 1;
			Element result;
			if (flag)
			{
				result = element;
			}
			else
			{
				XYZ point = (fi.Location as LocationPoint).Point;
				double division = 0.25;
				IList<PlanarFace> list = null;
				double num = 0.0;
				YJKLine hyline = null;
				int num2 = 0;
				foreach (Element element2 in intersectElementSet)
				{
					FamilyInstance familyInstance = element2 as FamilyInstance;
					bool flag2 = familyInstance == null;
					if (!flag2)
					{
						list = this.GetAllPlanarFaces(doc, familyInstance);
						bool flag3 = list == null || list.Count < 2;
						if (!flag3)
						{
							this.ExcludeNotSuitFaces(ref list, point, division);
							bool flag4 = num2 == 0;
							if (flag4)
							{
								hyline = this.GetNearFaceLine(list, point, division);
								num = this.GetDistancePointToHYLine(hyline, point);
								element = familyInstance;
								num2++;
							}
							else
							{
								YJKLine nearFaceLine = this.GetNearFaceLine(list, point, division);
								double distancePointToYJKLine = this.GetDistancePointToHYLine(nearFaceLine, point);
								bool flag5 = distancePointToYJKLine < num;
								if (flag5)
								{
									hyline = nearFaceLine;
									num = distancePointToYJKLine;
									element = familyInstance;
								}
							}
						}
					}
				}
				bool flag6 = hyline != null;
				if (flag6)
				{
					lineOnBeamFace = hyline.Line;
				}
				result = element;
			}
			return result;
		}

		private void ExcludeNotSuitFaces(ref IList<PlanarFace> suitFaces, XYZ layPoint, double division)
		{
			IList<PlanarFace> list = new List<PlanarFace>();
			foreach (PlanarFace planarFace in suitFaces)
			{
				bool flag = this.BeVerticalFace(planarFace, division, layPoint);
				if (flag)
				{
					list.Add(planarFace);
				}
			}
			suitFaces = list;
		}

		private double GetDistancePointToHYLine(YJKLine hyLine, XYZ point)
		{
			hyLine.MakeUnBound();
			XYZ project = hyLine.GetProject(point);
			return project.DistanceTo(new XYZ(point.X, point.Y, project.Z));
		}

		private List<PlanarFace> GetAllPlanarFaces(Autodesk.Revit.DB.Document doc, FamilyInstance fiBeam)
		{
			IList<PlanarFace> familyInstanceSurface = UnifiedModified.GetFamilyInstanceSurface(doc, fiBeam);
			LocationCurve locationCurve = fiBeam.Location as LocationCurve;
			bool flag = locationCurve == null;
			List<PlanarFace> result;
			if (flag)
			{
				result = null;
			}
			else
			{
				Curve curve = locationCurve.Curve;
				double num = 0.0001;
				XYZ xyz = curve.GetEndPoint(0).Subtract(curve.GetEndPoint(1)).Normalize();
				xyz = xyz.CrossProduct(new XYZ(0.0, 0.0, 1.0)).Normalize();
				List<PlanarFace> list = new List<PlanarFace>();
				foreach (PlanarFace planarFace in familyInstanceSurface)
				{
					bool flag2 = planarFace == null;
					if (!flag2)
					{
						XYZ xyz2 = planarFace.FaceNormal();
						bool flag3 = xyz2.IsAlmostEqualTo(xyz, num) || xyz2.IsAlmostEqualTo(-1.0 * xyz, num);
						if (flag3)
						{
							list.Add(planarFace);
						}
					}
				}
				result = list;
			}
			return result;
		}

		private YJKLine GetNearFaceLine(IList<PlanarFace> suitFaces, XYZ layPoint, double division)
		{
			YJKLine hyline = null;
			double num = 0.0;
			for (int i = 0; i < suitFaces.Count; i++)
			{
				bool flag = i == 0;
				if (flag)
				{
					hyline = this.GetLayLine(suitFaces[i], division);
					num = this.GetDistancePointToHYLine(hyline, layPoint);
				}
				else
				{
                    YJKLine layLine = this.GetLayLine(suitFaces[i], division);
					double distancePointToYJKLine = this.GetDistancePointToHYLine(layLine, layPoint);
					bool flag2 = distancePointToYJKLine < num;
					if (flag2)
					{
						hyline = layLine;
						num = distancePointToYJKLine;
					}
				}
			}
			return hyline;
		}

		private bool BeVerticalFace(PlanarFace pFace, double division, XYZ layPoint)
		{
			YJKLine layLine = this.GetLayLine(pFace, division);
			XYZ project = layLine.GetProject(layPoint);
			YJKLine hyline = new YJKLine(project, new XYZ(layPoint.X, layPoint.Y, project.Z));
			return layLine.IsVertical(hyline.Line);
		}

		private double GetPointToLineDistance(YJKLine hyLine, XYZ point)
		{
			return hyLine.GetDistance(point);
		}

		private YJKLine GetLayLine(PlanarFace pFace, double division)
		{
			YJKLine result = null;
			IList<Edge> planarFaceEdges = UnifiedModified.GetPlanarFaceEdges(pFace);
			XYZ xyz = new XYZ(0.0, 0.0, 1.0);
			List<Curve> list = new List<Curve>();
			double num = 0.0001;
			foreach (Edge edge in planarFaceEdges)
			{
				XYZ edgeVector = this.GetEdgeVector(edge);
				bool flag = edgeVector.IsAlmostEqualTo(xyz, num) || edgeVector.IsAlmostEqualTo(-1.0 * xyz, num);
				if (flag)
				{
					list.Add(edge.AsCurve());
				}
			}
			bool flag2 = list.Count == 2;
			if (flag2)
			{
				XYZ divisionPiont = this.GetDivisionPiont(list.First<Curve>(), division);
				XYZ divisionPiont2 = this.GetDivisionPiont(list.Last<Curve>(), division);
				result = new YJKLine(divisionPiont, divisionPiont2);
			}
			return result;
		}

		private XYZ GetEdgeVector(Edge edge)
		{
			Curve curve = edge.AsCurve();
			return curve.GetEndPoint(0).Subtract(curve.GetEndPoint(1)).Normalize();
		}

		private XYZ GetDivisionPiont(Curve curve, double division)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			bool flag = hyendPoint.Z < hyendPoint2.Z;
			if (flag)
			{
				hyendPoint = curve.GetEndPoint(1);
				hyendPoint2 = curve.GetEndPoint(0);
			}
			double num = hyendPoint.DistanceTo(hyendPoint2) * division;
			XYZ xyz = hyendPoint2.Subtract(hyendPoint).Normalize();
			return hyendPoint.Add(num * xyz);
		}

		private void SetAngle(Autodesk.Revit.DB.Document doc, Element elem, Element intersectingBeam, Line beamLine, ref double deviatValue)
		{
			Parameter parameter = elem.GetParameter("侧向支撑总高度");
			XYZ point = (elem.Location as LocationPoint).Point;
			XYZ xyzpoint = beamLine.Project(point).XYZPoint;
			double num = 0.0;
			Parameter parameter2 = elem.GetParameter("抗震连接构件高度");
			bool flag = parameter2 != null && parameter2.HasValue;
			if (flag)
			{
				num = parameter2.AsDouble();
			}
			double num2 = point.DistanceTo(new XYZ(xyzpoint.X, xyzpoint.Y, point.Z));
			double num3 = point.DistanceTo(new XYZ(point.X, point.Y, xyzpoint.Z));
			bool flag2 = point.Z < xyzpoint.Z;
			if (flag2)
			{
				num3 = -num3;
			}
			bool flag3 = parameter != null;
			if (flag3)
			{
				double num4 = 0.0;
				bool hasValue = parameter.HasValue;
				if (hasValue)
				{
					num4 = parameter.AsDouble();
				}
				double num5 = Math.Atan((num2 - num) / (num4 - num3 - num)) * 180.0 / Math.PI;
				bool flag4 = num5 < 22.5 || num5 > 67.5;
				if (flag4)
				{
					deviatValue = 0.0;
					YJKMessageBox.Information("抗震组件遇梁自动调整角度无法生成组件，请手动调整！");
				}
				else
				{
					bool flag5 = (num4 - num3) * 304.8 < 420.0;
					if (flag5)
					{
						this.crossBeamNotLayNum++;
					}
					else
					{
						Parameter parameter3 = elem.GetParameter(Autodesk.Revit.DB.BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
						bool flag6 = parameter3 != null && !parameter3.IsReadOnly && parameter3.HasValue;
						if (flag6)
						{
							double num6 = parameter3.AsDouble();
							parameter3.Set(num6 - num3);
						}
						bool flag7 = !parameter.IsReadOnly;
						if (flag7)
						{
							parameter.Set(num4 - num3);
						}
						Parameter parameter4 = elem.GetParameters("侧向支撑角度").FirstOrDefault<Parameter>();
						bool flag8 = parameter4 != null && !parameter4.IsReadOnly && num4 - num3 != 0.0;
						if (flag8)
						{
							parameter4.Set(num5 * Math.PI / 180.0);
						}
						Parameter parameter5 = elem.GetParameters("横向装置可见性").FirstOrDefault<Parameter>();
						bool flag9 = parameter5 != null && parameter5.HasValue;
						if (flag9)
						{
							parameter5.Set(0);
						}
					}
				}
			}
		}

		private Document doc;

		private UIDocument uiDoc;

		private DlgAddSeismicComponent dlg;

		private SeismicComponentModel scm;

		private string exMessage;

		private Transaction tran = null;

		private FamilySymbol fs = null;

		private HSType hsType;

		private double fixedThickness = 0.0;

		private int crossBeamNotLayNum = 0;
	}
}
